<script setup lang="ts">
import {onMounted, Ref, ref, watch} from "vue";
// import AgoraRTM from 'agora-rtx';
import {useSysStore} from "stores/sysStore";
import {useQuasar} from "quasar";
import eventBus from "src/utils/eventBus";
import {Wss} from "src/utils/type";
import VoiceToText from "pages/components/voiceToText.vue";
import {conf} from "src/utils/APIClient";
import {userBehavior} from "src/utils/util";

let $q = useQuasar()
let sysStores = useSysStore();
let RTMConfig:any;

onMounted(()=>{
  RTMConfig = {
    appId: sysStores.wssMessage.message.app_id,
    channel: sysStores.wssMessage.message.channel_name,
    token: sysStores.wssMessage.message.rtc_token,
    uid: sysStores.userInfo.id,
  }
  // if (!sysStores.userInfo.id)  RTMConfig.uid = localStorage.getItem("userId");
  initRtmConnect();
});

// let {RTM} = AgoraRTM;//multi_message
let rtmClient = {};

watch(()=>sysStores.wssMessage,(newVal)=>{
  let msg:Wss = (newVal as Wss);
  //如果收到
  if (msg.message_type == 'multi_message'){
    rtmClient.publish(RTMConfig.channel, JSON.stringify({
      type: 'text',
      message: msg.message
    }), {channelType: 'MESSAGE'});
  }
},{
  deep: true,
})

const initRtmConnect = async () => {
  if (process.env.DEV){
    window.AgoraRTM = (await import("agora-rtx"));
  }
  rtmClient = new window.AgoraRTM.RTM(RTMConfig.appId, RTMConfig.uid+'');
  rtmClient.addEventListener("message", event => {
    let scrollDiv = document.getElementById('scrollDiv');
    let message = JSON.parse(event.message);
    //tips.success($q, '来自' + event.publisher + '的消息： ' + event.message)

    //如果是命令，需要处理命令相关的动作，但无需显示信息
    if (message.type == 'command')
      return handleCommand(message)

    //创建白板后，需要rtm通知所有人进入
    if (message.type == 'boardNotify' && event.publisher != sysStores.userInfo.id)
      return boardNotify(message);

    //如果是普通文本消息，直接进行展示，无需特殊操作
    if (message.type == 'text')
      sysStores.RTMlog.push({
        from:event.publisher,
        content:isJsonString(message.message),
      })
      setTimeout(()=>{
        scrollDiv.scrollTop = scrollDiv.scrollHeight;
      })
  });

  await rtmClient.login({token: RTMConfig.token});
  await rtmClient.subscribe(RTMConfig.channel);
}

//输入框发送RTM消息（点击和enter）
let inputValue: Ref<any> = ref('');
const publishMessage = async () => {
  await rtmClient.publish(RTMConfig.channel, JSON.stringify({
    type: 'text',
    message: inputValue.value
  }), {channelType: 'MESSAGE'});
  userBehavior({
    operation_type_id:'send_im_text',
    operation_content:inputValue.value
  })
  inputValue.value = '';
}

//收到的消息是工作人员或坐席发送的白板配置消息，需要处理相关动作，
const boardNotify = async (msg) => {
  if (msg.type == 'boardNotify' && !sysStores.boardConfig.roomToken){
    sysStores.wssMessage = {
      message_type:'create_room_resp',
      message:{
        appIdentifier:msg.message.appIdentifier,
        roomToken:msg.message.roomToken,
        region:msg.message.region,
        uuid:msg.message.uuid,
      }
    }
  }
}
/**
 * 如果收到的是命令command，则通知videoCalling,处理相关的动作。但是这里只有群众才需要处理命令
 * @param msg 命令内容
 * 命令往往是工作人员或坐席发送给群众的，因此只需要群众进行处理
 */
const handleCommand = (msg:any) => {
  if(sysStores.userInfo.role_id != 1) return;
  eventBus.$emit('receiveCommand', msg.message)
}

const isJsonString = (str:string) => {
  let json = {}
  if(!isNaN(Number(str))) return str; //JSON.parse('1')==> 结果为number 1，如果是这种情况，需要直接返回该字符串，不做任何操作
  try {
    json = JSON.parse(str)
    return json;
  } catch (e) {
    return str;
  }
}

eventBus.$on('leaveChannel',async ()=>{
    try {
      rtmClient.logout(RTMConfig.channel);
      sysStores.boardConfig = {};
    } catch (e) {
      console.log(e)
    }
})

//收到通过阿里云语音转换之后文本信息，需要发送到rtm中
eventBus.$on('voiceText',async (text)=>{
  await rtmClient.publish(RTMConfig.channel, JSON.stringify({
    type: 'text',
    message: text
  }), {channelType: 'MESSAGE'});
  userBehavior({
    operation_type_id:'send_im_voice',
    operation_content:inputValue.value
  })
})

//videoCalling发出命令（命令群众共享屏幕/上传文件到白板），通过rtm向所有人发送
eventBus.$on('sendCommand',async (command:string)=>{
  await rtmClient.publish(RTMConfig.channel, JSON.stringify({
    type: 'command',
    message: command
  }), {channelType: 'MESSAGE'});
})

//白板创建成功以后，利用RTM的能力通知频道中的其他人全部进入白板，并传递白板的配置信息
eventBus.$on('sendBoardConfig',async (boardMsg:Board)=>{
  await rtmClient.publish(RTMConfig.channel, JSON.stringify({
    type: 'boardNotify',
    message: boardMsg
  }), {channelType: 'MESSAGE'});
})




//上传文件到RTM中
const uploadFiles = async () => {
  (document.getElementById('files') as HTMLElement).click()
}
eventBus.$on('uploadFilesBack', async (res) => {
  res.forEach( async (item) => {
    await rtmClient.publish(RTMConfig.channel, JSON.stringify({
      type: 'text',
      message: JSON.stringify(item),
    }), {channelType: 'MESSAGE'});
    userBehavior({
      operation_type_id:'send_file',
      operation_content:item.fileName
    })
  })
});
const downFile = (file) => {
  userBehavior({
    operation_type_id:'download_file',
    operation_content:file.fileName
  })
  window.location.href = `${conf.host}/download/object?bkt=${file.bucket}&obj=${file.fileName}`
}
const downFileFromAgent = (file:any) => {
  userBehavior({ operation_type_id:'download_kg_material'})
  let url = `${conf.host}/download/customize/files?bkt=510600000000`
  let token = localStorage.getItem('token')
  file.fileList.forEach(x => {
    url += `&obj=${x.url}`
  })
  url += '&token=' + token
  window.open(url);
}

</script>

<template>
  <div class="rtm-out">
    <div class="talk-out" id="scrollDiv">
      <!--      <div class="tit">与坐席1的交谈</div>-->
      <div class="talk-list" :class="x.from == sysStores.userInfo.id?'me':'side'" v-for="x in sysStores.RTMlog">
<!--        <img class="user-icon element" src="../../assets/images/worker.png">-->
        <div class="user-icon element">{{x.from}}</div>
        <div class="content element">
          <div v-if="typeof x.content == 'string'">{{x.content}}</div>
          <template v-else>
            <div class="file-care" v-if="x.content.eventName">
              <div class="tit">{{x.content.eventName}}：</div>
              <div class="tips">需要提交以下材料：</div>
              <div class="file-list">
                <div class="list" v-for="(y,i) in x.content.fileList">{{++i}}，{{y.name}}</div>
              </div>
              <div class="operate" @click="downFileFromAgent(x.content)">
                <span>下载样本</span>
              </div>
            </div>
            <div class="file-one" v-if="x.content.bucket" @click="downFile(x.content)">
              <q-icon name="description" style="color: #494949;"></q-icon>
              <span>{{x.content.fileName}}</span>
            </div>
          </template>
        </div>
      </div>
    </div>
    <div class="input-out">
      <textarea v-model="inputValue" @keydown.enter="publishMessage"></textarea>
      <div class="send">
        <svg class="icon send-icon file" aria-hidden="true"><use xlink:href="#icon-wenjianjia" @click="uploadFiles"></use></svg>
        <voice-to-text></voice-to-text>
        <svg class="icon send-icon" aria-hidden="true"><use xlink:href="#icon-fasong" @click="publishMessage"></use></svg>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.rtm-out {
  height: 100%;
  border-top: 1px solid gainsboro;
  border-right: 1px solid gainsboro;

  .talk-out::-webkit-scrollbar {
    display: none; /* Chrome, Safari, Edge */
  }

  .talk-out {
    width: 100%;
    height: calc(100% - 155px);
    //background-color: gainsboro;
    background-image: linear-gradient(to top, #e6e9f0 0%, #eef1f5 100%);
    //border-radius: 10px;
    overflow-y: auto;
    padding: 10px 0;

    .tit {

    }

    .talk-list {
      display: flex;
      padding: 10px;

      .user-icon {
        width: 35px;
        height: 35px;
        border-radius: 35px;
        background: #53affd;
        text-align: center;
        line-height: 35px;
        color: white;
      }

      .content {
        max-width: calc(100% - 60px);
        min-height: 40px;
        margin-left: 10px;
        margin-right: 10px;
        background-color: white;
        border-radius: 10px;
        padding: 10px;
        color: grey;
        letter-spacing: 3px;
        .file-care{
          .tips{
            font-size: 12px;
            color: grey;
          }
          .operate{
            display: flex;
            justify-content: end;
            cursor: pointer;
            padding-top: 10px;
          }
          .operate:hover{
            color: #409eff;
          }
        }
        .file-one{
          cursor: pointer;
          display: flex;
          justify-content: start;
          align-items: center;
          i {
            font-size: 24px;
            margin-right: 10px;
          }
        }
        .file-one:hover{
          color: #409eff;
        }
      }
    }

    .me {
      justify-content: end;

    }
    /* 交换后的顺序 */
    .me .element:first-child {
      order: 2;
    }

    .me .element:last-child {
      order: 1;
    }
  }

  .input-out {
    padding: 10px;
    width: 100%;
    height: 150px;
    background-image: linear-gradient(to top, #e6e9f0 0%, #eef1f5 100%);
    border-radius: 10px;
    margin-top: 5px;
    border-top: 1px solid gainsboro;

    textarea {
      width: 100%;
      height: 80px;
      border: 0;
      background-image: linear-gradient(to top, #e6e9f0 0%, #eef1f5 100%);
      outline: none;
      font-size: 16px;
      text-indent: 3px;
    }

    .send {
      display: flex;
      justify-content: end;

      .send-icon {
        width: 30px;
        height: 30px;
        transition: all .2s ease;
        cursor: pointer;
        color: #494949;
      }
      .file{
        margin-right: 10px;
      }

      .send-icon:hover {
        transform: scale(1.2);
        transition: all .2s ease;
      }
    }
  }
}
</style>
